﻿using System;
using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;

namespace Cyss.Core
{
    /// <summary>
    /// JSON 格式化帮助类
    /// </summary>
    public static class JsonHelper
    {

        private static JsonSerializerOptions Options { set; get; }

        static JsonHelper()
        {
            Options = new JsonSerializerOptions();
            Options.PropertyNamingPolicy = null;
            Options.IgnoreNullValues = true;
            Options.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
            Options.Converters.Add(new OperateResultJsonConverterFactory());
            Options.Converters.Add(new DatetimeJsonConverter());
            Options.Converters.Add(new EncryptStringJsonConverter());
        }

        /// <summary>
        /// 将对象转换为json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string SerializeObject(object obj)
        {
            return JsonSerializer.Serialize(obj, Options);
        }

        /// <summary>
        /// 将对象转换为json字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToSerializeObject(this object obj)
        {
            return JsonSerializer.Serialize(obj, Options);
        }

        /// <summary>
        /// 将字符串转换对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static T DeserializeObject<T>(string strJson)
        {
            return JsonSerializer.Deserialize<T>(strJson, Options);
        }

        /// <summary>
        /// 将字符串转换对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object DeserializeObject(string strJson, Type type)
        {
            return JsonSerializer.Deserialize(strJson, type, Options);
        }


        /// <summary>
        /// 将字符串转换对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static T ToDeserializeObject<T>(this string strJson)
        {
            return JsonSerializer.Deserialize<T>(strJson, Options);
        }
        /// <summary>
        /// 将字符串转换对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object ToDeserializeObject(this string strJson, Type type)
        {
            return JsonSerializer.Deserialize(strJson, type, Options);
        }




        /// <summary>
        /// 将json字符串格式化输出
        /// </summary>
        /// <param name="jsonString">json字符串</param>
        /// <returns></returns>
        public static string JsonFormat(this string jsonString)
        {
            if (string.IsNullOrWhiteSpace(jsonString))
            {
                return string.Empty;
            }
            var strArr = jsonString.ToCharArray();
            System.Text.StringBuilder jsonForMatStr = new System.Text.StringBuilder();
            int level = 0;
            for (int index = 0; index < strArr.Length; index++)//将字符串中的字符逐个按行输出
            {
                //获取s中的每个字符
                char c = strArr[index];

                //level大于0并且jsonForMatStr中的最后一个字符为\n,jsonForMatStr加入\t
                if (level > 0 && '\n' == jsonForMatStr.ToString().LastOrDefault())
                {
                    jsonForMatStr.Append(getLevelStr(level));
                }
                //遇到"{"和"["要增加空格和换行，遇到"}"和"]"要减少空格，以对应，遇到","要换行
                switch (c)
                {
                    case '{':
                    case '[':
                        jsonForMatStr.Append(c + "\n");
                        level++;
                        break;
                    case ',':
                        jsonForMatStr.Append(c + "\n");
                        break;
                    case '}':
                    case ']':
                        jsonForMatStr.Append("\n");
                        level--;
                        jsonForMatStr.Append(getLevelStr(level));
                        jsonForMatStr.Append(c);
                        break;
                    default:
                        jsonForMatStr.Append(c);
                        break;
                }
            }
            return jsonForMatStr.ToString();
        }

        private static String getLevelStr(int level)
        {
            System.Text.StringBuilder levelStr = new System.Text.StringBuilder();
            for (int levelI = 0; levelI < level; levelI++)
            {
                levelStr.Append("\t");
            }
            return levelStr.ToString();
        }
    }
}
